package com.qinglei.recoup.hmp.controller;

import com.qinglei.recoup.common.domain.CommonRes;
import com.qinglei.recoup.common.exception.RecoupException;
import com.qinglei.recoup.hmp.pojo.vo.HmpSleepReportMoreVO;
import com.qinglei.recoup.hmp.pojo.vo.healthReport.HealthReportDayVo;
import com.qinglei.recoup.hmp.pojo.vo.healthReport.SnListVo;
import com.qinglei.recoup.hmp.pojo.vo.healthReport.TopVo;
import com.qinglei.recoup.hmp.service.QingLeiHmpGqqService;
import com.qinglei.recoup.system.domain.RealTimeMonitoring;
import com.qinglei.recoup.system.domain.VitalSignsAlarm;
import com.qinglei.recoup.system.manager.RadarDataMessageConsumer;
import com.qinglei.recoup.system.pojo.*;
import com.qinglei.recoup.system.service.MonitorTimeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * @author superman
 * @date 2022/6/6$ 20:17$
 */
@Api(tags = "清雷二开")
@Slf4j
@RestController
@RequestMapping("/health/report")
public class QingLeiHmpGqqController {

    @Autowired
    private QingLeiHmpGqqService qingLeiHmpGqqService;

    /*
     * 接口设计说明:  后台已经开启了 逻辑删除
     * 1. 栗剑 将他们的 床位id 传给我们, 我们将其作为我们这边的床位名称, 这样就有了对应关系
     *      如果 他们不传, 也可以, 我们自己生成床位名称, 目前不影响业务
     * 2. 绑定时, 清雷这边如果 发现设备未解绑: 有 2 种 处理方案
     *      2.1 方案一: 返回提示, 设备sn未解绑
     *      2.2 方案二: 直接解绑原床位, 绑定新床位
     *
     *
     */

    @GetMapping("/addDeviceSnBingBedEvent")
    @ApiOperation(value = "设备sn绑定事件", notes = "设备sn绑定事件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sn", value = "监测仪设备SN码(8或12个字符)", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "type", value = "监测仪绑定类型(2-床 3-卫生间)", paramType = "query", dataType = "string", required = false),
            @ApiImplicitParam(name = "buildId", value = "楼唯一标识", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "floorId", value = "层唯一标识", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "roomId", value = "房间唯一标识", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "bedId", value = "床位唯一标识", paramType = "query", dataType = "string", required = true)
    })
    public CommonRes<Object> addDeviceSnBingBed(@RequestParam(value = "sn", required = true) String sn,
                                                @RequestParam(value = "type", required = false) String type,
                                                @RequestParam(value = "buildId", required = true) String buildId,
                                                @RequestParam(value = "floorId", required = true) String floorId,
                                                @RequestParam(value = "roomId", required = true) String roomId,
                                                @RequestParam(value = "bedId", required = true) String bedId) {
        return qingLeiHmpGqqService.deviceSnBingBed(sn, type, buildId, floorId, roomId, bedId);
    }

    @GetMapping("/deviceSnDeBingBedEvent")
    @ApiOperation(value = "设备sn解绑事件", notes = "设备sn解绑事件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sn", value = "监测仪设备SN码(8或12个字符)", paramType = "query", dataType = "string", required = true)
    })
    public CommonRes<Object> deviceSnDeBingBed(@RequestParam(value = "sn", required = true) String sn) {
        return qingLeiHmpGqqService.deviceSnDeBingBed(sn);
    }

    @GetMapping("/deviceSn/isExist")
    @ApiOperation(value = "判断设备sn号是否存在", notes = "通过设备sn号判断设备是否可用")
    @ApiImplicitParam(name = "sn", value = "设备SN码", paramType = "query", dataType = "string", required = true)
    public CommonRes<Object> deviceSnIsExist(String sn) {
        return qingLeiHmpGqqService.deviceSnIsExist(sn);
    }

    @GetMapping("/health/report/oneDay")
    @ApiOperation(value = "查询日健康报告", notes = "查询日健康报告")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sn", value = "设备SN码", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "startDate", value = "查询开始日期，格式：2021-01-06", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "endDate", value = "查询结束日期，格式：2021-01-06", paramType = "query", dataType = "string", required = true)
    })
    public CommonRes<List<HealthReportDayVo>> getsleepReportOneDay(String[] sn, String startDate, String endDate) {
        return qingLeiHmpGqqService.getsleepReportOneDay(sn, startDate, endDate);
    }

    @GetMapping("/health/report/moreDay")
    @ApiOperation(value = "查询多日健康报告", notes = "查询多日健康报告")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sn", value = "设备SN码", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "startDate", value = "查询开始日期，格式：2021-01-06", paramType = "query", dataType = "string", required = true),
            @ApiImplicitParam(name = "endDate", value = "查询结束日期，格式：2021-01-06", paramType = "query", dataType = "string", required = true)
    })
    public CommonRes<List<HmpSleepReportMoreVO>> getsleepReportMoreDay(String[] sn, String startDate, String endDate) {
        return qingLeiHmpGqqService.getsleepReportMoreDay(sn, startDate, endDate);
    }

    @PostMapping("/queryMoraleTopList")
    @ApiOperation(value = "情绪指数排行榜", notes = "跌倒风险指数排行榜/活力值排行榜/情绪值排行榜")
    public CommonRes<List<TopVo>> queryMoraleTopList(@RequestParam(value = "offset", required = false, defaultValue = "1") Integer offset,
                                                     @RequestBody SnListVo vo) {
        return qingLeiHmpGqqService.queryMoraleTopList(offset, vo.getSnList());
    }

    @PostMapping("/queryFailTopList")
    @ApiOperation(value = "跌倒风险指数排行榜", notes = "跌倒风险指数排行榜/活力值排行榜/情绪值排行榜")
    public CommonRes<List<TopVo>> queryFailTopList(@RequestParam(value = "offset", required = false, defaultValue = "1") Integer offset,
                                                   @RequestBody SnListVo vo) {
        return qingLeiHmpGqqService.queryFailTopList(offset, vo.getSnList());
    }

    @PostMapping("/queryVitalityTopList")
    @ApiOperation(value = "活力值排行榜", notes = "跌倒风险指数排行榜/活力值排行榜/情绪值排行榜")
    public CommonRes<List<TopVo>> queryVitalityTopList(@RequestParam(value = "offset", required = false, defaultValue = "1") Integer offset,
                                                       @RequestBody SnListVo vo) {
        return qingLeiHmpGqqService.queryVitalityTopList(offset, vo.getSnList());
    }

    @GetMapping("/list")
    @ApiOperation(value = "查询用户的健康数据列表")
    public CommonRes<List<HealthVO>> getHealthList(String[] snList, String startDate, String endDate) {
        List<HealthVO> list = qingLeiHmpGqqService.searchHealthList(snList, startDate, endDate);
        return CommonRes.ok(list);
    }

    // 设备检测值 查询, 修改
    // 新增床位时, 会 使用上层 的检测时间段设置, 即 使用 该房间 的检测时间段 作为 床的 检测时间

    // ?? 床的 各种阈值 在哪里设置???

    //t_real_time_monitoring    呼吸/心跳 阈值设置表    实时监测类别（1-呼吸阈值  2-心跳阈值）
    //在衡量呼吸以及心跳频次时，往往用bpm这个单位。标准的心率范围是60到100bpm，标准的呼吸范围是12到20bpm
    //t_vital_signs_alarm     生命体征报警阈值表   生命体征报警类别(1.离床过久2.跌倒3.呼吸过速4.呼吸暂停过久5.心跳过缓6.心跳过速)
    //t_health_big_data     健康大数据阈值表    健康大数据类别(1.健康报告2.查看健康报告3.查看/修改老人信息4.老人健康数据5.员工功效数据6.设备运营数据7.实时设备运行)

    // 离床时间阈值   查询, 修改, 新增
    // 生命体征报警阈值表   查询, 修改, 新增
    // 呼吸/心跳 阈值设置表  (实时监测表)   查询, 修改, 新增

    // 阈值逻辑 ==>  新增 床位时, 使用 默认的阈值,
    // 设备绑定床位时, 使用 床位的 阈值设置
    // 修改 阈值,  ==>  批量更改
    // 重置 某项阈值
    // 1. 呼吸/心跳 阈值设置表  给
    //      实时监测类别: 1-呼吸阈值  2-心跳阈值
    //      白天/晚上:  1-白天  2-晚上
    // 2. 生命体征报警阈值表
    //      生命体征报警类别(1.离床过久2.跌倒3.呼吸过速4.呼吸暂停过久5.心跳过缓6.心跳过速)


    @PostMapping("/select/vital/signs/alarm")
    @ApiOperation(value = "设备生命体征报警阈值-批量查询", notes = "设备生命体征报警阈值-批量查询")
    public CommonRes<List<VitalSignsAlarm>> selectVitalSignsAlarm(@RequestBody SnListVo vo) {
        return qingLeiHmpGqqService.selectVitalSignsAlarm(vo.getSnList());
    }

    @PostMapping("/update/vital/signs/alarm")
    @ApiOperation(value = "设备生命体征报警阈值-批量修改", notes = "设备生命体征报警阈值-批量修改")
    public CommonRes<Object> updateVitalSignsAlarm(@RequestBody List<VitalSignsAlarm> vitalSignsAlarmList) {
        return qingLeiHmpGqqService.updateVitalSignsAlarm(vitalSignsAlarmList);
    }

    @GetMapping("/default/vital/signs/alarm")
    @ApiOperation(value = "生命体征报警阈值-查询默认值", notes = "设备监测值/生命体征报警阈值-查询默认值")
    public CommonRes<List<VitalSignsAlarm>> defaultVitalSignsAlarm() {
        return qingLeiHmpGqqService.defaultVitalSignsAlarm();
    }

    @PostMapping("/select/real/time/monitoring")
    @ApiOperation(value = "呼吸/心跳 阈值设置-批量查询", notes = "呼吸/心跳 阈值设置-批量查询")
    public CommonRes<List<RealTimeMonitoring>> selectRealTimeMonitoring(@RequestBody SnListVo vo) {
        return qingLeiHmpGqqService.selectRealTimeMonitoring(vo.getSnList());
    }

    @PostMapping("/update/real/time/monitoring")
    @ApiOperation(value = "呼吸/心跳 阈值设置-批量修改", notes = "呼吸/心跳 阈值设置-批量修改")
    public CommonRes<Object> updateRealTimeMonitoring(@RequestBody List<RealTimeMonitoring> realTimeMonitoringList) {
        return qingLeiHmpGqqService.updateRealTimeMonitoring(realTimeMonitoringList);
    }

    @GetMapping("/default/real/time/monitoring")
    @ApiOperation(value = "呼吸/心跳 阈值设置-查询默认值", notes = "呼吸/心跳 阈值设置-查询默认值")
    public CommonRes<List<RealTimeMonitoring>> defaultRealTimeMonitoring() {
        return qingLeiHmpGqqService.defaultRealTimeMonitoring();
    }


    @Autowired
    private MonitorTimeService monitorTimeService;

    @GetMapping("/query/settings/tree")
    @ApiOperation(value = "查询检测仪工作配置 (楼层房间床) 树")
    public CommonRes<List<MonitorInfoTreeVO>> getMonitorInfoTree(@RequestParam(value = "sn", required = true) String sn) {
        return CommonRes.ok(qingLeiHmpGqqService.getMonitorInfoTree(sn));
    }

    @ApiOperation(value = "添加检测仪工作时间段")
    @PostMapping("/workTime")
    public CommonRes<Object> addMonitorTime(@Valid @RequestBody AddMonitorTimeParam param) {
        try {
            monitorTimeService.addMonitorTime(param);
        } catch (RecoupException e) {
            return CommonRes.failed(e.getMessage());
        } catch (Exception e) {
            log.error("addMonitorTime error", e);
            return CommonRes.failed(e.getMessage());
        }
        return CommonRes.ok();
    }

    @ApiOperation(value = "修改检测仪工作时间段")
    @PutMapping("/workTime")
    public CommonRes<Object> updateMonitorTime(@Valid @RequestBody UpdateMonitorTimeParam param) {
        try {
            monitorTimeService.updateMonitorTime(param);
        } catch (RecoupException e) {
            return CommonRes.failed(e.getMessage());
        } catch (Exception e) {
            log.error("updateMonitorTime error", e);
            return CommonRes.failed(e.getMessage());
        }
        return CommonRes.ok();
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "类型 1-床 2-房间 3-层 4-楼", paramType = "path", dataType = "int", required = true),
            @ApiImplicitParam(name = "monitorTimeId", value = "监控时间ID", paramType = "path", dataType = "int", required = true)
    })
    @ApiOperation(value = "删除检测仪工作时间段")
    @DeleteMapping("/workTime/{type}/{monitorTimeId}")
    public CommonRes<Object> delMonitorTime(@PathVariable @NotNull Integer type, @PathVariable @NotNull Integer monitorTimeId) {
        try {
            monitorTimeService.delMonitorTime(type, monitorTimeId);
        } catch (Exception e) {
            log.error("delMonitorTime error", e);
            return CommonRes.failed(e.getMessage());
        }
        return CommonRes.ok();
    }

    @ApiOperation(value = "修改离床时间阀值")
    @PutMapping("/outBedTimeout")
    public CommonRes<Object> updateOutBedTimeout(@Valid @RequestBody UpdateOutBedTimeoutParam param) {
        return monitorTimeService.updateOutBedTimeout(param);
    }


    @Autowired
    private RadarDataMessageConsumer test;

    @ApiOperation(value = "设备上下线消息测试接口")
    @GetMapping("/device/online")
    public CommonRes<Object> deviceOnLine(String sn, Integer devStatus) {
        test.Test(sn, devStatus);
        return CommonRes.ok("已发送!!");
    }

}
